package iweb

import (
	"encoding/json"
	log "github.com/sirupsen/logrus"
	"github.com/tietang/props/v3/kvs"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
)

const (
	TIME_SECONDS_FORMAT = "20060102150405"
	// GzipHeaderValue is the header value of "gzip".
	GzipHeaderValue = "gzip"
	// AcceptEncodingHeaderKey is the header key of "Accept-Encoding".
	AcceptEncodingHeaderKey = "Accept-Encoding"
	GMT                     = "Mon, 02 Jan 2006 15:04:05 GMT"
)

var Exclueds = []string{
	"**/*.ico",
	"**/*.js",
	"**/*.css",
	"**/*.png",
	"**/*.gif",
	"**/*.jpg",
	"**/fonts/**",
	"**/images/**",
	"**/css/**",
	"**/js/**",
}

func GetInfoHandler(conf kvs.ConfigSource) (string, http.HandlerFunc) {
	startTime := time.Now()
	appName := conf.GetDefault("app.name", "unknown-app")

	info := make(map[string]interface{})
	info["appName"] = appName
	info["time"] = startTime
	infodata, _ := json.Marshal(info)
	return "/info", func(w http.ResponseWriter, r *http.Request) {
		w.Write(infodata)
	}
}
func GetHealthHandler(conf kvs.ConfigSource) (string, http.HandlerFunc) {
	startTime := time.Now()
	appName := conf.GetDefault("app.name", "unknown-app")

	health := make(map[string]interface{})
	health["appName"] = appName
	health["time"] = startTime
	health["description"] = ""
	health["status"] = "UP"
	return "/health", func(w http.ResponseWriter, r *http.Request) {
		health["time"] = time.Now()
		healthdata, _ := json.Marshal(health)
		w.Write(healthdata)
	}
}

func healthAndInfoEndpoint(conf kvs.ConfigSource, mux *http.ServeMux) {
	mux.HandleFunc(GetInfoHandler(conf))
	mux.HandleFunc(GetHealthHandler(conf))
}

func InjectEnv(conf kvs.ConfigSource) {
	pwd, _ := os.Getwd()
	log.Info("inject dir: ", pwd)
	files := conf.Strings("ac.domain.switch.files")
	apiPlaceholder := conf.GetDefault("ac.domain.placeholder.api", "http://dev.tietang.wang")
	staticPlaceholder := conf.GetDefault("ac.domain.placeholder.static", "http://devadmin.tietang.wang/console")
	apiDomain := conf.GetDefault("ac.domain.api", "http://devadmin.tietang.wang")
	staticDomain := conf.GetDefault("ac.domain.static", "http://devadmin.tietang.wang/console")
	log.Info("replace: ", apiPlaceholder, " to ", apiDomain)
	log.Info("replace: ", staticPlaceholder, " to ", staticDomain)
	for _, file := range files {
		f := filepath.Join(pwd, file)
		log.Info("pre inject file: ", f)
		dir := filepath.Dir(f)
		fileInfos, err := ioutil.ReadDir(dir)
		if err != nil {
			log.Error(err)
			continue
		}
		for _, fi := range fileInfos {
			if !fi.IsDir() {
				f2 := filepath.Join(dir, fi.Name())
				if ok, e := filepath.Match(f, f2); ok && e == nil {
					log.Info("process file: ", f2)
					Replace(f2, []string{apiPlaceholder, staticPlaceholder}, []string{apiDomain, staticDomain})
				}
			}
		}
	}
}

func Replace(file string, olds, news []string) {
	Backup(file)
	//文件类型需要进行过滤
	buf, err := ioutil.ReadFile(file)
	if err != nil {
		//err
		if err != nil {
			log.Error("read file: ", err)
		}
		return
	}
	content := string(buf)
	newContent := content
	//替换
	for i, old := range olds {
		newContent = strings.Replace(newContent, old, news[i], -1)
	}

	//重新写入
	err = ioutil.WriteFile(file, []byte(newContent), 0)
	if err != nil {
		log.Error("write file: ", err)
	}
}

func Backup(file string) {
	src, err := os.Open(file)
	if err != nil {
		return
	}
	defer src.Close()
	now := time.Now()
	dst, err := os.OpenFile(file+"."+now.Format(TIME_SECONDS_FORMAT), os.O_WRONLY|os.O_CREATE, 0644)
	if err != nil {
		return
	}
	defer dst.Close()
	w, err := io.Copy(dst, src)
	if err != nil {
		log.Error("copy file: ", file, " ", w, " ", err)
	}
}
